#include <qio/qio.h>  // NOLINT
#include <cstdio>
#include <iostream>
#include <chrono>
#include <thread>

#define CATCH_CONFIG_RUNNER

#include "catch.hpp"

using namespace qio;  // NOLINT

constexpr static char CERT_FILE[] = "C://Users//Suzhen//Desktop//ca.crt";
constexpr static char KEY_FILE[] = "C://Users//Suzhen//Desktop//ca.key";

/*
TEST_CASE("loop.RunEvery", "[loop timer]") {
  EventLoop loop;
  int count = 0;
  for (int i = 0; i < 1024; ++i) {
    loop.RunEvery(500, [i](Timer *timer) { printf("task: %d \n", i); });
  }
  loop.RunEvery(1000, [&loop, &count](Timer *timer) {
    printf("RunAfter :%d\n", ++count);
    if (count == 10) {
      // timer->Stop();
      loop.Stop();
    }
  });

  loop.Run();
  printf("program will exit...\n");
}
*/

//TEST_CASE("loop.IO", "[loop io]") {
int main() {

    std::ios::sync_with_stdio(false);

    SSL_library_init();
    SSL_load_error_strings();

    EventLoop loop;

    TcpServerConfig config;
    config.reuse_port = true;
    config.reuse_addr = true;
    config.address = IPAddress("0.0.0.0", 40443);
    config.ssl_helper = nullptr;// std::make_shared<SSLConfig>(CERT_FILE, KEY_FILE);
    TcpServer server(&loop, config);

    server.OnEstablished([](TcpConn *conn) {
        std::cout << "Connected ID: " << conn->GetConnId()
                  << ",Address: " << conn->GetRemoteAddress().ToString()
                  << std::endl;
    });
    server.OnDisconnected([](TcpConn *conn) {
        std::cout << "Disconnected Connection ID: " << conn->GetConnId()
                  << ",Address: " << conn->GetRemoteAddress().ToString()
                  << std::endl;
    });
    server.OnMessage([](TcpConn *conn, Buffer *buf) {
        const auto data = buf->ReadAll();
        std::cout << "Connection ID: " << conn->GetConnId()
                  << ",Address: " << conn->GetRemoteAddress().ToString()
                  << std::endl
                  << "Message: "
                  << std::string(data.data(), data.size())
                  << std::endl
                  << "============================================================"
                  << std::endl;
        conn->Send("hello world");
    });
    server.Start();

    std::thread{[&server, &loop]() {
        std::this_thread::sleep_for(std::chrono::seconds(120));
        printf("server will stop\n");
        server.Stop();
        loop.Stop();
    }}
            .detach();

    loop.Run();
    puts("TcpServer has Exited....");
    return 0;
}
//}

/*
TEST_CASE("simple test", "[Test]") {
  printf("simple test complete \n");
}

TEST_CASE("Map 插入测试", "[map]") {
  typedef std::map<std::string, int> Map;
  typedef std::pair<Map::key_type, int> Entry;
  Map mp;
  auto it = mp.emplace(Entry("x", 1));
  auto erase_r = mp.erase("x");
  REQUIRE(erase_r == 1);
  REQUIRE(it.second);
  REQUIRE(mp.emplace(Entry("x", 2)).second);
}

TEST_CASE("TestAnyCast", "[TestAny]") {
  qio::Any any(1);
  auto v = any.Cast<int>();
  qio::Any any2(2);
}


TEST_CASE("SWAP PTR", "[swap]") {
  int *x = new int(1);
  int *y = new int(10);
  std::swap(x, y);
  printf("%d,%d\n", *x, *y);
}



//int main(int argc, char *argv[]) {
//  int result = Catch::Session().run(argc, argv);
//  return result;
//}

*/
